home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / telecomm / sticpsrc.lzh / SOURCE.ARC / ENVIRON.C < prev    next >
C/C++ Source or Header  |  1990-05-30  |  11KB  |  448 lines

  1. /* support for environment variables */
  2.  
  3. #include <stdio.h>
  4. #include <ctype.h>
  5.  
  6. #include "global.h"
  7. #include "environ.h"
  8.  
  9. extern char startup[],on_exit[],userfile[],hosts[],fingerpath[],mailspool[],
  10.         mailqdir[],routeqdir[],alias[],tmpdir[];
  11.  
  12. /* default names and values for environment vars */
  13.  
  14. char STARTUP[]      = "NETSTART";        /* Initialization file */
  15. char ONEXIT[]      = "NETEXIT";        /* Initialization file */
  16. char USERFILE[]      = "NETUSERS";        /* Authorized FTP users and passwords */
  17. char HOSTS[]      = "NETHOSTS";        /* Network host table */
  18. char FINGERPATH[] = "NETFINGER";    /* Finger file path */
  19. char MAILSPOOL[]  = "NETMAILS";        /* Incoming mail */
  20. char MAILQDIR[]      = "NETMAILQ";        /* Outgoing mail spool */
  21. char ROUTEQDIR[]  = "NETROUTEQ";    /* queue for router */
  22. char ALIAS[]      = "NETALIAS";        /* the alias file */
  23. #ifdef ATARI_ST
  24. char TIMEZONE[]      = "TIMEZONE";        /* local time zone */
  25. char TMPDIR[]      = "TMPDIR";        /* temp files directory */
  26. char ATARI_STYLE[]= "ENVSTYLE";        /* Environment style DOS/Atari */
  27. #endif
  28. #ifdef MSDOS
  29. char TIMEZONE[]      = "TZ";        /* local time zone */
  30. #endif
  31.  
  32. struct env_default env_defs[] = {
  33.     STARTUP,    startup,    /* Initialization file */
  34.     ONEXIT,        on_exit,    /* Termination file */
  35.     USERFILE,    userfile,    /* Authorized FTP users and passwords */
  36.     HOSTS,        hosts,        /* Network host table */
  37.     FINGERPATH,    fingerpath,    /* Finger file path */
  38.     MAILSPOOL,    mailspool,    /* Incoming mail */
  39.     MAILQDIR,    mailqdir,    /* Outgoing mail spool */
  40.     ROUTEQDIR,    routeqdir,    /* queue for router */
  41.     ALIAS,        alias,        /* the alias file */
  42. #ifdef ATARI_ST
  43.     TIMEZONE,    "GMT:0",    /* default local timezone */
  44.     TMPDIR,        tmpdir,        /* temp files directory */
  45. #endif
  46. #ifdef MSDOS
  47.     TIMEZONE,    "GMT0",        /* default local timezone */
  48. #endif
  49.     NULLCHAR, NULLCHAR
  50. };
  51.  
  52. struct env_var *the_env = NULLENV;
  53. char **env_envp = NULLCHRP;        /* stores last envp from make_env */
  54. static char **env_wenvp;        /* working copy for fill_env */
  55. char *env_env = NULLCHAR;        /* stores last env from make_env */
  56. static char *env_wenv;            /* working copy for fill_env */
  57.  
  58. #ifdef ATARI_ST
  59. static int atari_style = 1;        /* Atari-style (not MSDOS) environment */
  60. #endif
  61.  
  62. extern char nospace[];            /* No space!! message */
  63.  
  64. /* lookup/create an environment-variable node */
  65. static struct env_var *
  66. env_node (name,creat)
  67. char *name;
  68. int creat;
  69. {
  70.     register struct env_var **env_pp = &the_env;
  71.     register char *p,*q;
  72.     int r;
  73.  
  74.     while (*env_pp != NULLENV) {
  75.         p = (*env_pp)->name;    /* compare current name */
  76.         q = name;            /* with searched name */
  77.  
  78.         while (*p == *q) {
  79.         if (*p == '\0' || *q == '='){
  80.             break;
  81.         }
  82.         p++;
  83.         q++;
  84.         }
  85.  
  86.         if (*q == '=')        /* test end-result */
  87.         r = -*p;
  88.         else
  89.         r = *q - *p;
  90.  
  91.         if (!r)            /* found it? */
  92.         return *env_pp;        /* then return the node */
  93.  
  94.         if (r < 0)            /* smaller? */
  95.         env_pp = &(*env_pp)->left;    /* go left */
  96.         else
  97.         env_pp = &(*env_pp)->right;    /* else go right */
  98.     }
  99.  
  100.     /* not found, create a new node? */
  101.  
  102.     if (!creat)
  103.         return NULLENV;
  104.  
  105.     for (p = name; *p != '\0' && *p != '='; p++) /* find namelength */
  106.         ;
  107.  
  108.     if ((*env_pp = (struct env_var *)
  109.         calloc(1,sizeof(struct env_var) + p - name)) == NULLENV){
  110.         printf(nospace);
  111.         return NULLENV;
  112.     }
  113.  
  114.     memcpy((*env_pp)->name,name,p - name);    /* copy name */
  115.  
  116.     return *env_pp;                /* return created node */
  117. }
  118.  
  119. /* read the value of an environment variable (of the local copy, that is) */
  120. /* it returns a pointer to the actual value, so you can do multiple calls */
  121. /* to getenv, and save the resulting pointers. (the Aztec getenv returns  */
  122. /* a pointer to a static area overwritten by each call, UNIX(tm) doesn't) */
  123. char *getenv (name)
  124. #if (defined(MSC) || defined(__TURBOC__))
  125. const                    /* agree with stdlib.h declaration */
  126. #endif
  127. char *name;
  128. {
  129.     register struct env_var *env_p;
  130.  
  131.     if ((env_p = env_node(name,0)) == NULLENV)
  132.         return NULLCHAR;        /* no space, does not exist */
  133.  
  134.     return env_p->value;        /* return value or NULL */
  135. }
  136.  
  137. /* read the value of an environment variable (of the local copy, that is) */
  138. /* same as getenv(), but return "" instead of NULL when it does not exist */
  139. char *getnenv (name)
  140. char *name;
  141. {
  142.     char *rv;
  143.  
  144.     if ((rv = getenv(name)) == NULL)
  145.         rv = "";            /* NULL replaced by "" */
  146.  
  147.     return rv;
  148. }
  149.  
  150. /* set the value of an environment variable */
  151. struct env_var *
  152. setenv (name,value)
  153. char *name;
  154. char *value;
  155. {
  156.     register struct env_var *env_p;
  157.  
  158.     if ((env_p = env_node(name,1)) == NULLENV)
  159.         return NULLENV;        /* no space */
  160.  
  161.     if (env_p->value_alloc)
  162.         free(env_p->value);
  163.  
  164.     env_p->value = value;
  165.     return env_p;
  166. }
  167.  
  168. /* read the supplied environment at program startup */
  169. void
  170. readenv (envp)
  171. char *envp[];
  172. {
  173.     register int i;
  174.     register char *p;
  175.     char *name,*value;
  176.     struct env_default *defs;
  177.  
  178.     /* read the fixed default values */
  179.  
  180.     for (defs = env_defs; defs->name != NULLCHAR; defs++)
  181.         setenv(defs->name,defs->value);
  182.  
  183.     /* then, override these with environment values */
  184.  
  185. #if (defined(MSDOS) && !defined(MSC) && !defined(__TURBOC__))
  186.     /* special treatment for Aztec C which does not pass envp to main() */
  187.     {
  188.         extern short _PSP;        /* segment of the PSP */
  189.         char *buf[2];
  190.         char far *fp;
  191.  
  192.         if ((buf[1] = malloc(512)) == NULLCHAR) /* allocate a near buf */
  193.         return;
  194.  
  195.         /* get far ptr to env, whose SEG is in 22'th WORD of the PSP */
  196.         fp = (char far *) ((long) (((short far *) ((long) _PSP << 16))[22]) << 16);
  197.  
  198.         while (*fp != '\0'){    /* scan the env */
  199.         p = buf[1];
  200.         while ((*p++ = *fp++) != '\0') /* copy a NAME=value line */
  201.            ;            /* to a near buffer (8086...) */
  202.  
  203.         if (isalpha(*buf[1]))    /* is it a valid name? */
  204.             dosetenv(2,buf);    /* than fake a setenv command */
  205.         }
  206.  
  207.         free(buf[1]);
  208.     }
  209. #else
  210.     /* all others use the third arg of main() (envp) */
  211.  
  212.     if (envp == NULLCHRP)        /* no environment? */
  213.         return;            /* nothing to read... */
  214.  
  215.     for (i = 0; (name = envp[i]) != NULLCHAR; i++) {
  216.         value = NULLCHAR;
  217.         for (p = name; *p != '\0'; p++)
  218.         if (*p == '=') {
  219. #ifdef ATARI_ST
  220.             if (p[1] != '\0')    /* when no \0, it is MSDOS-style */
  221.             atari_style = 0;
  222. #endif
  223.             value = p + 1;    /* MSDOS-style has value after = */
  224.             break;
  225.         }
  226.  
  227. #ifdef ATARI_ST
  228.         if (atari_style)        /* Atari-style has separate value */
  229.         if ((value = envp[++i]) == NULLCHAR) /* get the value */
  230.             i--;        /* protect against passing end of env */
  231.  
  232.         if (!strncmp(name,"ARGV",p - name))
  233.         continue;        /* ignore ARGV= var on Atari */
  234. #endif
  235. #ifdef MSDOS
  236.         if (!isalpha(name[0]))    /* ignore funny var names */
  237.         continue;
  238. #endif
  239.  
  240.         if (value != NULLCHAR)
  241.         setenv(name,value);
  242.     }
  243. #endif
  244.  
  245. #ifdef ATARI_ST
  246.     if (atari_style)
  247.         setenv(ATARI_STYLE,"1");    /* define atari-style env */
  248. #endif
  249. }
  250.  
  251. /* get the number of items in the currently stored environment */
  252. static unsigned
  253. env_count(env_v)
  254. register struct env_var *env_v;
  255. {
  256.     if (env_v == NULLENV)            /* end of tree? */
  257.         return 0;
  258.  
  259.     return (env_count(env_v->left) +    /* return sum of all nodes */
  260.         ((env_v->value != NULLCHAR)? 1 : 0) +
  261.         env_count(env_v->right));
  262. }
  263.  
  264. /* get the size of the currently stored environment */
  265. static unsigned
  266. env_size(env_v)
  267. register struct env_var *env_v;
  268. {
  269.     if (env_v == NULLENV)            /* end of tree? */
  270.         return 0;
  271.  
  272.     return (env_size(env_v->left) +        /* return sum of all nodes */
  273.         ((env_v->value != NULLCHAR)?
  274.             (strlen(env_v->name) + strlen(env_v->value) + 2)
  275. #ifdef ATARI_ST
  276.             + atari_style        /* Atari-style requires extra byte */
  277. #endif
  278.         :
  279.             0) +
  280.         env_size(env_v->right));
  281. }
  282.  
  283. /* fill a buffer with the environment vars */
  284. static
  285. fill_env(env_v)
  286. register struct env_var *env_v;
  287. {
  288.     register char *p;
  289.  
  290.     if (env_v != NULLENV) {            /* not end of tree? */
  291.         fill_env(env_v->left);
  292.  
  293.         if (env_v->value != NULLCHAR){    /* not unset? */
  294.         *env_wenvp++ = env_wenv;    /* put pointer in envp array */
  295.  
  296.         for (p = env_v->name; *p != '\0'; ) /* store name */
  297.             *env_wenv++ = *p++;
  298.  
  299.         *env_wenv++ = '=';
  300. #ifdef ATARI_ST
  301.         if (atari_style)
  302.             env_wenv++;            /* put that